<!-- 
  分而治之的思想
    面对复杂问题的一种处理方式，拆分成多个小问题，再放在整体中
  什么是组件化开发？
    将一个页面拆分成一个个小的功能块，每个功能块完成属于自己这部分独立的功能
  组件化思想思考
    将一个完整的页面分成很多个组件，
    每个组件都用于实现页面的一个功能块，
    而每个组件又可以进行细分，
    而组件本身又可以在多个地方进行复用
  组件化思想的应用：
    尽可能的将页面拆分成一个个小的、可复用的组件
    代码更加方便组织和管理，并且扩展性也更强


  React组件的划分
      根据组件的定义方式：函数组件、类组件
      根据组件内部是否有状态需要维护：无状态组件、有状态组件
      根据组件的不同职责：展示型组件、容器型组件
    最主要是关注数据逻辑和UI展示的分离
      函数组件、无状态组件、展示型组件主要关注UI的展示
      类组件、有状态组件、容器组件主要关注数据逻辑
    异步组件、高阶组件等

  组件的定义
    1、组件的名称大写字符开头（无论类组件还是函数组件）
    2、JSX中严格区分大小写(大写字符开头的会当成组件，普通html标签必须是小写字符开头的)
    3、组件分类
      3.1、类组件
        3.1.1、类组件需要继承自React.Component
        3.1.2、类组件必须实现render函数
        3.1.3、使用class定义一个组件
         （1）constructor是可选的，通常在constructor中初始化一些数据
         （2）constructor中的this.state中维护的是组件内部的数据
         （3）render()方法是class组件中唯一必须实现的方法   *****
      3.2、函数组件
        3.2.1、没有this对象；
        3.2.2、没有内部状态state（hooks可以维护状态）；
        3.2.3、没有生命周期，也会被更新并挂载，但是没有生命周期。
    4、在ES6之前，可以通过create-react-class模块来定义类组件名，但是目前官网建议使用es6的class类定义

    5、render函数的返回值/函数式组件中return返回的内容
      5.1、render函数被调用时，会检查this.props和this.state的变化并返回一下类型之一
        5.1.1、React元素
          （1）通常通过jsx创建
          （2）例如：<div />会被React渲染为DOM节点，<MyComponent />会被React渲染为自定义组件
          （3）无论<div />还是<MyComponent />均为React元素
        5.1.2、数组或fragments
          使得render方法可以返回多个元素
        5.1.3、Portals可以渲染子节点到不同的DOM子树中
          Portals 端口
        5.1.4、字符串或数值类型：在DOM中会被渲染为文本节点
        5.1.5、布尔类型或null：什么都不渲染
    6、生命周期---从创建到销毁的过程
      了解组件的生命周期可以让我们在最合适的地方完成自己想要的功能
      6.1、生命周期和生命周期函数的概念
        6.1.1、生命周期是一个抽象的概念，在生命周期的整个过程，分成了很多阶段
          （1）装载阶段（Mount）,组件第一次在DOM树中被渲染的过程；
          （2）更新过程（Update）,组件状态发生变化，重新更新渲染的过程；
          （3）卸载阶段（Unmount）,组件从DOM树中被移除的过程。
        6.1.2、React内部为了告诉我们当前处于哪些阶段，会对组件内部实现的某些函数进行回调，这些函数就是生命周期函数
          （1）componentDidMount函数：组件已经挂载到DOM上时，就会回调；
          （2）componentDidUpdate函数：组件已经发生了更新时，就会回调；
          （3）componentWillUnmount函数：组件即将被移除时，就会回调。
          可在这些回调函数中编写自己的逻辑代码，来完成自己的需求功能。
      在谈React生命周期时，主要谈的是类的生命周期，因为函数组件是没有生命周期函数的（后面可通过hooks来模拟一些生命周期的回调）
      6.2、生命周期的执行顺序
        6.2.1、挂载阶段(Mount)-> 更新阶段(Update)-> 卸载阶段(Unmount)
          挂载
            constructor -> render ->componentDidMount
              constructor
                如果不初始化state或不进行方法绑定，则不需要为React组件实现构造函数
                制作两件事
                  通过给this.state赋值对象来初始化内部的state
                  为事件绑定this实例
              componentDidMount
                会在组件挂载后（插入DOM树中）立即调用
                可执行的操作：
                  依赖与DOM的操作，如获取元素高度、宽度等，ref等
                  发送网络请求，
                  添加一些订阅、事件监听，如WebSocket等，
          更新
            new props/setState/forceUpdate -> componentDidUpdate
              componentDidUpdate
                会在更新后被立即调用，首次渲染不会执行
                可执行的操作：
                  组件更新后，对DOM操作，
                  如果对更新前后的props进行了比较，也可进行网络请求（例如当props未发生变化时，则不会执行网络请求）
          卸载
            移除 -> componentWillUnmount
              componentWillUnmount
                会在组件卸载前被立即调用，首次渲染不会执行
                可执行的操作：
                  清理订阅、事件监听等资源，清除timer，取消网络请求或清除在componentDidMount()中创建的订阅等
      6.3、不常用的生命周期
        6.3.1、getDerivedStateFromProps
          state的值在任何时候都依赖于props时使用；该方法返回一个对象来更新state
        6.3.2、getSnapshotBeforeUpdate
          在React更新DOM之前回调一个函数，可以获取DOM更新前的一些信息（比如滚动位置）
        6.3.3、shouldComponentUpdate
          该生命周期函数很常用，性能优化时详解
    7、组件的嵌套
      7.1、组件间的通信，数据传递
        7.1.1、父子组件通信：父组件通过props向子组件传递数据，子组件通过props接收数据
        7.1.2、兄弟组件通信：兄弟组件之间可以通过index或ref进行通信
 -->